﻿using System.Collections.Generic;
using System.IO;


namespace Development.Network.Msg
{
    public class MsgSn
    {
        BinaryWriter writer;
        MemoryStream mStream;
        public MsgSn()
        {
            mStream = new MemoryStream();
            writer = new BinaryWriter(mStream);
        }

        public int CalcLen()
        {
            int msgLen = (int)mStream.Position;
            writer.Seek(0, SeekOrigin.Begin);
            writer.Write(msgLen);
            return msgLen;
        }

        public byte[] GetMsg()
        {
            return mStream.ToArray();
        }


        public MsgSn Write(int val)
        {
            writer.Write(val);
            return this;
        }

        public MsgSn Write(uint val)
        {
            writer.Write(val);
            return this;
        }

        public MsgSn Write(ushort val)
        {
            writer.Write(val);
            return this;
        }

        public MsgSn Write(short val)
        {
            writer.Write(val);
            return this;
        }

        public MsgSn Write(byte val)
        {
            writer.Write(val);
            return this;
        }

        public MsgSn Write(long val) //64bit
        {
            writer.Write(val);
            return this;
        }

        public MsgSn Write(float val)
        {
            writer.Write(val);
            return this;
        }

        public MsgSn Write(bool val)
        {
            writer.Write(val);
            return this;
        }

        public MsgSn Write(string val)
        {
            if(val == null)
            {
                val = string.Empty;
            }
            writer.Write(val);
            return this;
        }

        public MsgSn Write(byte[] val)
        {
            int len = val.Length;
            writer.Write(len);
            writer.Write(val);
            return this;
        }



        public MsgSn Write<T>(List<T> val) where T : ISn, new()
        {
            int len = val.Count;
            writer.Write(len);
            foreach (T t in val)
            {
                t.Sn(this);
            }
            return this;
        }

        public MsgSn Write(List<int> val)
        {
            int len = val.Count;
            writer.Write(len);
            foreach (int t in val)
            {
                writer.Write(t);
            }
            return this;
        }

        public MsgSn Write(List<uint> val)
        {
            int len = val.Count;
            writer.Write(len);
            foreach (uint t in val)
            {
                writer.Write(t);
            }
            return this;
        }

        public MsgSn Write(List<short> val)
        {
            int len = val.Count;
            writer.Write(len);
            foreach (short t in val)
            {
                writer.Write(t);
            }
            return this;
        }

        public MsgSn Write(List<ushort> val)
        {
            int len = val.Count;
            writer.Write(len);
            foreach (ushort t in val)
            {
                writer.Write(t);
            }
            return this;
        }

        public MsgSn Write(List<byte> val)
        {
            int len = val.Count;
            writer.Write(len);
            foreach (byte t in val)
            {
                writer.Write(t);
            }
            return this;
        }

        public MsgSn Write(List<long> val)
        {
            int len = val.Count;
            writer.Write(len);
            foreach (long t in val)
            {
                writer.Write(t);
            }
            return this;
        }

        public MsgSn Write(List<string> val)
        {
            int len = val.Count;
            writer.Write(len);
            foreach (string t in val)
            {
                this.Write(t);
            }
            return this;
        }



        public MsgSn Write(Dictionary<string, byte[]> val)
        {
            int len = val.Count;
            writer.Write(len);
            foreach (KeyValuePair<string, byte[]> keyValue in val)
            {
                this.Write(keyValue.Key);
                this.Write(keyValue.Value);
            }
            return this;
        }

        public MsgSn Write<K, V>(Dictionary<K, V> val)
            where K : ISn, new()
            where V : ISn, new()
        {
            int len = val.Count;
            writer.Write(len);
            foreach (KeyValuePair<K, V> keyValue in val)
            {
                keyValue.Key.Sn(this);
                keyValue.Value.Sn(this);
            }
            return this;
        }

        public MsgSn Write<V>(Dictionary<int, V> val) where V : ISn, new()
        {
            int len = val.Count;
            writer.Write(len);
            foreach (KeyValuePair<int, V> keyValue in val)
            {
                writer.Write(keyValue.Key);
                keyValue.Value.Sn(this);
            }
            return this;

        }

        public MsgSn Write<V>(Dictionary<long, V> Val) where V : ISn, new()
        {
            int len = Val.Count;
            writer.Write(len);
            foreach (KeyValuePair<long, V> kvp in Val)
            {
                writer.Write(kvp.Key);
                kvp.Value.Sn(this);
            }
            return this;
        }

        public MsgSn Write(Dictionary<int, long> val)
        {
            int len = val.Count;
            writer.Write(len);
            foreach (KeyValuePair<int, long> keyValue in val)
            {
                writer.Write(keyValue.Key);
                writer.Write(keyValue.Value);
            }
            return this;
        }

        public MsgSn Write(Dictionary<int, int> val)
        {
            int len = val.Count;
            writer.Write(len);
            foreach (KeyValuePair<int, int> keyValue in val)
            {
                writer.Write(keyValue.Key);
                writer.Write(keyValue.Value);
            }
            return this;
        }

        public MsgSn Write(Dictionary<int, ushort> val)
        {
            int len = val.Count;
            writer.Write(len);
            foreach (KeyValuePair<int, ushort> keyValue in val)
            {
                writer.Write(keyValue.Key);
                writer.Write(keyValue.Value);
            }
            return this;
        }

        public MsgSn Write(Dictionary<int, float> val)
        {
            int len = val.Count;
            writer.Write(len);
            foreach (KeyValuePair<int, float> keyValue in val)
            {
                writer.Write(keyValue.Key);
                writer.Write(keyValue.Value);
            }
            return this;
        }

        public MsgSn Write(Dictionary<int, string> val)
        {
            int len = val.Count;
            writer.Write(len);
            foreach (KeyValuePair<int, string> keyValue in val)
            {
                writer.Write(keyValue.Key);
                this.Write(keyValue.Value);
            }
            return this;
        }

        public MsgSn Write(Dictionary<ushort, int> val)
        {
            int len = val.Count;
            writer.Write(len);
            foreach (KeyValuePair<ushort, int> keyValue in val)
            {
                writer.Write(keyValue.Key);
                writer.Write(keyValue.Value);
            }
            return this;
        }

        public MsgSn Write(Dictionary<ushort, ushort> val)
        {
            int len = val.Count;
            writer.Write(len);
            foreach (KeyValuePair<ushort, ushort> keyValue in val)
            {
                writer.Write(keyValue.Key);
                writer.Write(keyValue.Value);
            }
            return this;
        }

        public MsgSn Write(Dictionary<ushort, string> val)
        {
            int len = val.Count;
            writer.Write(len);
            foreach (KeyValuePair<ushort, string> keyValue in val)
            {
                writer.Write(keyValue.Key);
                this.Write(keyValue.Value);
            }
            return this;
        }

        public MsgSn Write(Dictionary<string, int> val)
        {
            int len = val.Count;
            writer.Write(len);
            foreach (KeyValuePair<string, int> keyValue in val)
            {
                this.Write(keyValue.Key);
                writer.Write(keyValue.Value);
            }
            return this;
        }

        public MsgSn Write(Dictionary<string, ushort> val)
        {
            int len = val.Count;
            writer.Write(len);
            foreach (KeyValuePair<string, ushort> keyValue in val)
            {
                this.Write(keyValue.Key);
                writer.Write(keyValue.Value);
            }
            return this;
        }

        public MsgSn Write(Dictionary<string, string> val)
        {
            int len = val.Count;
            writer.Write(len);
            foreach (KeyValuePair<string, string> keyValue in val)
            {
                this.Write(keyValue.Key);
                this.Write(keyValue.Value);
            }
            return this;
        }

        public MsgSn Write<T>(T val) where T : ISn
        {
            val.Sn(this);
            return this;
        }
    }
}
